/*
* Class name: CreateCommand
*
* This Class acts as a parser between the UI and the different tasks. When the user enters an input the UI, the string of sentence
* minus the command is received by the createCommmand. It then looks for the keywords and updates the task attributes accordingly.
* The Keywords are: /t for task title, /de for task description, /l for task location, /pe for task person, /st for task start time
* /et for task end time, /d for task date and /pr for task priority.
*
* author@ A0100248W
*/

#pragma once
 
#include <assert.h>
#include <algorithm>
#include <regex>
#include <iostream>
#include <stdlib.h>
#include <assert.h>
#include "CommonConstant.h"
#include "ICommand.h"
#include "FloatingTask.h"
#include "DeadlineTask.h"
#include "TimedTask.h"


class CreateCommand :
	public ICommand
{
public:
	CreateCommand(string);
	~CreateCommand(void);

	string Execute();
	string Unexecute();
private:
	//FloatingTask _new_task;
	int index;
	FloatingTask* task;
	Storage* storage;
	string restOfCommand;
	void parser(string inputSentence);
	time_t currentTime;

	//@author A0100248W

	// takes in the string to check whether the input sentence contains the keywords
	bool comparisonString(string sentenceToBeChecked);
	bool checkKeyWord(string inputSentence, string keyWord);

	void updateTaskTime(struct tm& tempTime, vector<string>& task, vector<string>& timeTrack, string key, int index);
	void updateTaskPriority(int& TaskPriority, vector<string>& task, int index);

	// updates task name, task description, task location, task person depending on the input parameters.
	void updateTaskFeature(string& taskFeature, vector<string>& task, int index);
	void updateTaskDate(vector<string>& date, vector<string>& task, int index);
	

	void createTimedTask(string taskName,string taskDescription,string taskLocation, string taskPerson, int taskPriority, struct tm startTime,struct tm endTime);
	void createDeadlineTask(string taskName,string taskDescription,string taskLocation, string taskPerson, int taskPriority, struct tm endTime);
	void createFloatingTask(string taskName,string taskDescription,string taskLocation, string taskPerson, int taskPriority);

	//this methods checks if the /et has been entered and if not assigns a an end time one hour after start time.
	// It also checks if date has been assigned and if not gives it a tomorrow's date if the starting time is before 
	// current time or the today's date of the starting time is after current time.
	void attributesAssignmentStartTimeChange(struct tm& startTime, struct tm& endTime, struct tm currTime, bool endTimeChange, bool dateChecker);
	
	// This methods checks if date has been assigned and if not gives it a tomorrow's date if the starting time is before 
	// current time or the today's date of the starting time is after current time.
	void attributesAssignmentEndTimeChange(struct tm& endTime, struct tm currTime, bool endTimeChange, bool dateChecker);

	void clearSpaceAtEnd(string& inputSentence);
	string convertStringtoLower(string sentence);
	string convertStringtoUpper(string sentence);
	void eraseTask(vector<string>& task, int index);
	void resetTime();

	//matches /d and /st or /et keywords. It accesses whether which date to assign to start time and end time by analyzing their position
	// in the input statement
	void handleDate(vector<string>& date, vector<string>& trackTime, struct tm& startTime, struct tm& endTime);
	// takes in a date and assigns the date to a tm structure
	void assignDateToTime(struct tm& taskTime, vector<string> date);
	bool checkInvalidDate(int day, int month, int year);
	void extractDate(vector<string>& tmpDate, vector<string> date, struct tm& taskTime,int& tempDelete);

	//assign date when the date is in dd/mm/yyyy format. For example 12/11/2013
	void dateAssignmentNumbersFormat(smatch match, string date,int& day,int& month, int& year);
	//assign date when is in dd monthname yyyy or monthname dd yyyy format. For example 12 Nov/November 2013 or Nov 12 2013.
	void dateAssignmentMonthWordFormat(vector<string>& date, struct tm& tempTime, bool& singleDay,bool& singleMonth, bool& yearChecker);
	//assigns date when a day is entered or words like today, tomorrow or 'day after tomorrow' are used.
	void dateAssignmentDayFormat(vector<string>& date, struct tm& tempTime, bool& alternateFormatChecker);

	// it handles the time if user enters time in this format HH:MM (am/pm)
	void handleTimeTwelveHourFormat(string timeConvention ,int& hour);
	bool checkInvalidTimeSingle(struct tm taskTime);
	bool checkInvalidTimeCompare(struct tm startTime, struct tm endTime);
	// assesses which format of time is used to entered. It could be HH:MM(am/pm) or HHMM in 24 hours format.
	void selectTimeFormat(string tempsentence,int& hour,int& min);
	
	// =============================MESSAGES==============================
	//The messages are created for error handling as constant strings for easying viewing and
	//editing later..
	//===================================================================


	static const string MESSAGE_NO_USER_INPUT_AFTER_COMMAND;
	static const string MESSAGE_INVALID_INPUT_FORMAT;
	static const string MESSAGE_CREATE_UNDO_SUCCESSFULLY;
	static const string MESSAGE_INVALID_TIME;
	static const string MESSAGE_INVALID_DATE;
	static const string MESSAGE_INVALID_TIME_2;
	static const string MESSAGE_INVALID_INPUT_AFTER_KEY;
	static const string MESSAGE_INVALID_TIME_FORMAT;
	static const string MESSAGE_INVALID_PRIORITY;
	static const string MESSAGE_KEY_REPETITION;
	static const string MESSAGE_KEYWORD_INVALID;
	static const string MESSAGE_INVALID_STARTTIME_BEFORE_ENDTIME;
	static const string MESSAGE_TWO_DATES_ENTERED;


};

